package com.mk.magic_c.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mk.magic_c.dto.UserLoginVo;
import com.mk.magic_c.dto.UserRegisterVo;
import com.mk.magic_c.mapper.LoginTicketMapper;
import com.mk.magic_c.mapper.UserMapper;
import com.mk.magic_c.model.LoginTicket;
import com.mk.magic_c.model.User;
import com.mk.magic_c.service.UserService;
import com.mk.magic_c.utils.BusinessConstant;
import com.mk.magic_c.utils.MailClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author Magic Kong
 * @since 2021-10-02
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService, BusinessConstant {

    @Autowired
    private LoginTicketMapper loginTicketMapper;

    @Autowired
    private MailClient mailClient;

    @Autowired
    private TemplateEngine templateEngine;

    @Override
    public Map<String, Object> register(UserRegisterVo userRegisterVo) {
        User user = BeanUtil.toBean(userRegisterVo, User.class);

        if (user == null) {
            throw new IllegalArgumentException("用户参数异常");
        }
        Map<String, Object> result = new HashMap<>(3);
        // 空参校验
        if (StrUtil.isBlank(user.getUsername())) {
            result.put("userNameError", "用户名不能为空");
        }
        if (StrUtil.isBlank(user.getPassword())) {
            result.put("passwordError", "密码不能为空");
        }
        if (StrUtil.isBlank(user.getEmail())) {
            result.put("emailError", "邮箱不能为空");
        }
        // 如果有空的参数，直接返回错误结果集
        if (result.size() != 0) {
            return result;
        }

        // 用户名重复校验
        User byUserName = baseMapper.selectOne(new QueryWrapper<User>().eq("username", user.getUsername()));
        if (byUserName != null) {
            result.put("userNameError", "该用户名已被注册");
            return result;
        }

        // 邮箱重复校验
        User byEmail = baseMapper.selectOne(new QueryWrapper<User>().eq("email", user.getEmail()));
        if (byEmail != null) {
            result.put("emailError", "邮箱已被注册");
            return result;
        }
        //

        // 验证通过
        user.setType(0);
        user.setStatus(0);
        // 加盐加密
        user.setSalt(RandomUtil.randomString(5));
        user.setPassword(SecureUtil.md5(user.getPassword() + user.getSalt()));
        // 随机在线头像
        user.setHeaderUrl(String.format("https://cdn-community.codemao.cn/community_frontend/community_default_avatar/avatar_300x300_0%d.jpg", RandomUtil.randomInt(1, 8)));
        user.setCreateTime(new Date());
        user.setActivationCode(RandomUtil.randomString(5));
        this.save(user);

        // 给用户发激活邮件
        Context context = new Context();
        context.setVariable("email", user.getEmail());
        String activeUrl = String.format("http://localhost:9000/magic_c/user/active/%d/%s", user.getId(), user.getActivationCode());
        log.debug("activeUrl = " + activeUrl);
        context.setVariable("activeUrl", activeUrl);
        String emailContent = templateEngine.process("mail/activation", context);
        mailClient.sendMail(user.getEmail(), "牛客网账号激活邮件", emailContent);
        // size=0,表示注册成功
        return result;
    }

    @Override
    public int activeAccount(Integer id, String activationCode) {
        // 激活共有三种情况：成功，重复激活，失败
        User user = this.getById(id);
        if (user != null && StrUtil.equals(activationCode, user.getActivationCode())) {
            if (user.getStatus() == 0) {
                user.setStatus(1);
                this.updateById(user);
                return BusinessConstant.ACTIVE_SUCCESS;
            } else {
                return BusinessConstant.ACTIVE_DUPLICATION;
            }
        }
        return BusinessConstant.ACTIVE_FAILURE;
    }

    @Override
    public Map<String, String> login(UserLoginVo userLoginVo) {
        Map<String, String> result = new HashMap<>(3);
        // 1. 校验用户名和密码
        User user = this.getOne(new QueryWrapper<User>().eq("username", userLoginVo.getUsername()));
        if (user == null) {
            result.put("usernameError", "用户名不存在");
            return result;
        }

        String encrPass = SecureUtil.md5(userLoginVo.getPassword() + user.getSalt());
        if (!StrUtil.equals(user.getPassword(), encrPass)) {
            result.put("passwordError", "密码错误");
            return result;
        }
        // 2. 生成登陆凭证
        LoginTicket loginTicket = new LoginTicket();
        loginTicket.setStatus(0);
        loginTicket.setUserId(user.getId());
        loginTicket.setTicket(UUID.fastUUID().toString());
        if (userLoginVo.getRememberMe()) {
            // 点击了记住我，凭证有效期为 1个月
            loginTicket.setExpired(new Date(System.currentTimeMillis() + REMEMBER_ME_ON * 1000L));
        } else {
            // 未点击，凭证有效期为 12 小时
            loginTicket.setExpired(new Date(System.currentTimeMillis() + REMEMBER_ME_OFF * 1000L));
        }
        loginTicketMapper.insert(loginTicket);
        result.put("loginTicket", loginTicket.getTicket());
        return result;
    }
}
